package com.shycloud.mido.homework.service.impl;

import com.google.gson.JsonObject;
import com.shycloud.mido.common.api.constants.HomeWorkConstants;
import com.shycloud.mido.common.core.exception.BusinessException;
import com.shycloud.mido.common.security.util.SecurityUtils;
import com.shycloud.mido.homework.api.entity.MidoHomeworkComplateWeek;
import com.shycloud.mido.homework.api.vo.MidoHomeworkComplateVO;
import com.shycloud.mido.homework.mapper.MidoHomeworkComplateWeekMapper;
import com.shycloud.mido.member.api.feign.RemoteMemberService;
import com.shycloud.mido.member.api.vo.StudentVO;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.List;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.joy.zebra.common.push.JPushUtils;
import com.shycloud.mido.common.core.constant.CommonConstants;
import com.shycloud.mido.homework.api.entity.MidoHomeworkComplate;
import com.shycloud.mido.homework.api.entity.MidoHomeworkMain;
import com.shycloud.mido.homework.api.enums.JPushCodeEnum;
import com.shycloud.mido.homework.mapper.MidoHomeworkComplateMapper;
import com.shycloud.mido.homework.mapper.MidoHomeworkMainMapper;
import com.shycloud.mido.homework.service.MidoHomeworkComplateService;
import com.shycloud.mido.member.api.entity.MsgMain;
import com.shycloud.mido.member.api.entity.MsgMemberInfo;
import com.shycloud.mido.member.api.feign.RemotePushService;
import lombok.AllArgsConstructor;

/**
 * 作业完成业务实现类
 *
 * @author nianhua.jiang
 * @date 2021/8/18 9:56
 */
@Service
@AllArgsConstructor
public class MidoHomeworkComplateServiceImpl extends ServiceImpl<MidoHomeworkComplateMapper, MidoHomeworkComplate> implements
		MidoHomeworkComplateService {

	/** 作业完成情况 mapper */
	private final MidoHomeworkComplateMapper complateMapper;
	/** 作业完成情况 mapper 周报用 */
	private final MidoHomeworkComplateWeekMapper complateWeekMapper;
	/** 作业 mapper */
	private final MidoHomeworkMainMapper homeworkMainMapper;
	/** 站内信模块 feign */
	private final RemotePushService remotePushService;
	/** 用户模块 feign */
	private final RemoteMemberService remoteMemberService;

	/** 学生完成作业给教师提示信息标题：今日作业已完成 */
	private static final String SUBMIT_HOMEWORK_PUSH_TITLE = "今日作业已完成";

	/**
	 * 提交作业
	 *
	 * @param complate 作业完成信息
	 * @return java.lang.Boolean
	 * @author nianhua.jiang
	 * @date 2020/6/29 11:04
	 */
	@Override
	@Transactional(rollbackFor = Exception.class, timeout = 36000)
	public Boolean submitHomwork(MidoHomeworkComplateVO complate) {

		//检索作业表
		MidoHomeworkMain midoHomeworkMain = homeworkMainMapper.selectById(complate.getHomeworkId());
		if (midoHomeworkMain == null) {
			return false;
		}
		//如果为试听模式
		if (StringUtils.equals(HomeWorkConstants.AUDITION_MODE, midoHomeworkMain.getPlayingMode())) {
			//检索完成详情表，在完成次数上 +1
			MidoHomeworkComplate midoHomeworkComplate = complateMapper.selectOne(
					new QueryWrapper<MidoHomeworkComplate>().eq(MidoHomeworkComplate.COL_HOMEWORK_ID, complate.getHomeworkId()));
			if (midoHomeworkComplate != null) {
				//完成次数 + 1 并记录更新
				midoHomeworkComplate.setTotalScore(midoHomeworkComplate.getTotalScore() + 1);
				complateMapper.updateById(midoHomeworkComplate);
			} else {
				//创建时间
				complate.setCreateTime(new Date());
				//完成次数为 1
				complate.setTotalScore(1);
				//新增作业完成情况信息
				complateMapper.insert(complate);
			}

			MidoHomeworkComplate complateAfter = complateMapper.selectOne(
					new QueryWrapper<MidoHomeworkComplate>().eq(MidoHomeworkComplate.COL_HOMEWORK_ID, complate.getHomeworkId()));
			if (midoHomeworkMain.getTargetScore() < complateAfter.getTotalScore()
					|| midoHomeworkMain.getTargetScore().equals(complateAfter.getTotalScore())) {
				//已完成
				midoHomeworkMain.setStatus(HomeWorkConstants.COMPELTED);
			} else {
				//进行中
				midoHomeworkMain.setStatus(HomeWorkConstants.UNFINISHED);
			}
			homeworkMainMapper.updateById(midoHomeworkMain);
		}
		//其他模式
		else {
			if (complate.getTotalScore() < midoHomeworkMain.getTargetScore()) {
				return false;
			}
			//更新作业状态为【已完成】
			midoHomeworkMain.setStatus(HomeWorkConstants.COMPELTED);
			//更新
			homeworkMainMapper.updateById(midoHomeworkMain);

			//根据作业ID检索作业完成表，查询信息
			List<MidoHomeworkComplate> homeworkComplates = complateMapper.selectList(new QueryWrapper<MidoHomeworkComplate>()
					.eq(MidoHomeworkComplate.COL_HOMEWORK_ID, complate.getHomeworkId()));
			//提交时间
			complate.setCreateTime(new Date());

			if (homeworkComplates.size() > 0) {

				MidoHomeworkComplate midoHomeworkComplate = homeworkComplates.get(homeworkComplates.size() - 1);

				complate.setId(midoHomeworkComplate.getId());

				complateMapper.updateById(complate);
			} else {
				//新建完成详情表
				complateMapper.insert(complate);
			}
		}

		// 保存complate week 信息用于计算周报
		MidoHomeworkComplateWeek homeworkComplateWeek = new MidoHomeworkComplateWeek();
		BeanUtils.copyProperties(complate, homeworkComplateWeek);
		homeworkComplateWeek.setPlayingMode(midoHomeworkMain.getPlayingMode());
		complateWeekMapper.insert(homeworkComplateWeek);

		//推送作业 - 异常记录返回 true
		try {
			//推送消息的场合 : 不是试听作业 并且 是教师模式
			if (!HomeWorkConstants.AUDITION_MODE.equals(midoHomeworkMain.getPlayingMode()) && HomeWorkConstants.TEACHER_MODE
					.equals(midoHomeworkMain.getIsParentMode())) {

				// 查询此作业的批次ID，看是否这一组作业全部完成全部完成
				Long groupId = midoHomeworkMain.getGroupId();
				//作业开始时间
				String startDate = new SimpleDateFormat("yyyy-MM-dd").format(midoHomeworkMain.getStartDate());
				//获取作业信息
				List<MidoHomeworkMain> homeworkMains = homeworkMainMapper
						.getHomeworkPush(groupId, midoHomeworkMain.getPlayingMode(), startDate);
				//全完成才给推送
				boolean isPush = homeworkMains.stream().allMatch(x -> HomeWorkConstants.COMPELTED.equals(x.getStatus()));
				if (isPush) {
					// 获取教师的 memberId
					String memberId = homeworkMainMapper.getTeacherId(midoHomeworkMain.getTeacherId());
					// 推送消息
					String regId = homeworkMainMapper.getRegIdByMemberId(memberId);
					// 获取学生的昵称
					String studentName = homeworkMainMapper.getMemberNameByStuId(midoHomeworkMain.getStudentId());
					//旧版本推送内容为学生ID
					if (StringUtils.isEmpty(complate.getVersion())) {
						JSONArray jsonArray = new JSONArray();
						jsonArray.add(midoHomeworkMain.getStudentId());
						//推送 message
						JPushUtils
								.sendJMessage(JPushCodeEnum.J_PUSH_STUDENT_COMMIT_HOMEWORK.getType(), regId, jsonArray.toJSONString());
					}
					//新版本推送内容新增作业开始时间,用键值对形式返回
					else {
						JsonObject jsonObject = new JsonObject();
						jsonObject.addProperty("studentId", midoHomeworkMain.getStudentId());
						jsonObject.addProperty("startDate", startDate);
						JPushUtils.sendJMessage(JPushCodeEnum.J_PUSH_STUDENT_COMMIT_HOMEWORK.getType(), regId, jsonObject.toString());
					}
					//新增消息体 - 提交作业（完成作业）
					String msgId = addMsg("您的学生 " + studentName + " 已经完成了作业,快来看看吧", regId);
					//调用 feign 保存个人站内消息
					MsgMemberInfo msgMemberInfo = new MsgMemberInfo();
					//阅读状态：未读
					msgMemberInfo.setReadStatus("0");
					//创建时间
					msgMemberInfo.setCreateTime(LocalDateTime.now());
					//创建人 系统创建
					msgMemberInfo.setCreateUser("sys");
					//有效数据
					msgMemberInfo.setDelFlag(CommonConstants.STATUS_NORMAL);
					//发送方ID 0-系统发送
					msgMemberInfo.setFromId("0");
					//接收方ID - memberId
					msgMemberInfo.setToId(memberId);
					//消息信息
					msgMemberInfo.setMsgId(msgId);
					//作业数据
					msgMemberInfo.setHomeworkData(
							createHomeworkData(midoHomeworkMain, startDate, midoHomeworkMain.getStudentId(), studentName));
					//发送
					remotePushService.sendMsg(msgMemberInfo);
					//通知 APP 请求指定接口
					JPushUtils.sendJMessage(JPushCodeEnum.J_PUSH_APP_HOMEPAGE_VIEW.getType(), regId, "请调用 getMsgApp 接口");
					//推送消息
					JPushUtils.sendJPush(SUBMIT_HOMEWORK_PUSH_TITLE, "您的学生 " + studentName + " 已经完成了作业,快来看看吧", regId);
				}
			}

		} catch (Exception e) {
			return true;
		}

		return true;
	}

	/**
	 * 提交作业
	 *
	 * @param complate 作业完成信息
	 * @return java.lang.Boolean
	 * @author nianhua.jiang
	 * @date 2020/6/29 11:04
	 */
	@Override
	@Transactional(rollbackFor = Exception.class, timeout = 36000)
	public MidoHomeworkComplateWeek submitHomworkWeek(MidoHomeworkComplateVO complate) {

		//检索作业表
		MidoHomeworkMain midoHomeworkMain = homeworkMainMapper.selectById(complate.getHomeworkId());
		// 保存complate week 信息用于计算周报
		MidoHomeworkComplateWeek homeworkComplateWeek = new MidoHomeworkComplateWeek();
		if (midoHomeworkMain == null) {
			throw new BusinessException("提交作业失败");
		}
		//保存学生ID
		complate.setStudentId(midoHomeworkMain.getStudentId());

		//如果为试听模式
		if (StringUtils.equals(HomeWorkConstants.AUDITION_MODE, midoHomeworkMain.getPlayingMode())) {
			//检索完成详情表，在完成次数上 +1
			MidoHomeworkComplate midoHomeworkComplate = complateMapper.selectOne(
					new QueryWrapper<MidoHomeworkComplate>().eq(MidoHomeworkComplate.COL_HOMEWORK_ID, complate.getHomeworkId()));

			if (midoHomeworkComplate != null) {
				if (complate.getRecordingSrc() != null && !StringUtils.equals("null", complate.getRecordingSrc())) {
					midoHomeworkComplate.setRecordingSrc(midoHomeworkComplate.getRecordingSrc() + ";" + complate.getRecordingSrc());
				} else {
					midoHomeworkComplate.setRecordingSrc(midoHomeworkComplate.getRecordingSrc() + ";" + "");
				}
				//完成次数 + 1 并记录更新
				midoHomeworkComplate.setTotalScore(midoHomeworkComplate.getTotalScore() + 1);
				complateMapper.updateById(midoHomeworkComplate);
			} else {
				//创建时间
				complate.setCreateTime(new Date());
				//完成次数为 1
				complate.setTotalScore(1);
				//新增作业完成情况信息
				complateMapper.insert(complate);
			}

			BeanUtils.copyProperties(complate, homeworkComplateWeek);
			//已完成
			homeworkComplateWeek.setFlag("1");
			//作业模式
			homeworkComplateWeek.setPlayingMode(midoHomeworkMain.getPlayingMode());
			//memberId
			homeworkComplateWeek.setMemberId(SecurityUtils.getMember().getId());
			//曲目时长改用作业主表的曲目时长(因为需要分段/分小节，所以曲目的标准时长由前端进行计算)
			if (midoHomeworkMain.getMusicLength() != null) {
				homeworkComplateWeek.setMusicLength(midoHomeworkMain.getMusicLength());
			}
			complateWeekMapper.insert(homeworkComplateWeek);

			MidoHomeworkComplate complateAfter = complateMapper.selectOne(
					new QueryWrapper<MidoHomeworkComplate>().eq(MidoHomeworkComplate.COL_HOMEWORK_ID, complate.getHomeworkId()));

			if (midoHomeworkMain.getTargetScore() < complateAfter.getTotalScore()
					|| midoHomeworkMain.getTargetScore().equals(complateAfter.getTotalScore())) {
				//已完成
				midoHomeworkMain.setStatus(HomeWorkConstants.COMPELTED);
			} else {
				//进行中
				midoHomeworkMain.setStatus(HomeWorkConstants.UNFINISHED);
			}
			homeworkMainMapper.updateById(midoHomeworkMain);

		}

		//其他模式
		else {

			if (complate.getTotalScore() < midoHomeworkMain.getTargetScore()) {
				throw new BusinessException("分数没达标，提交失败");
			}

			//根据作业ID检索作业完成表，查询信息
			List<MidoHomeworkComplate> homeworkComplates = complateMapper.selectList(new QueryWrapper<MidoHomeworkComplate>()
					.eq(MidoHomeworkComplate.COL_HOMEWORK_ID, complate.getHomeworkId()));
			//提交时间
			complate.setCreateTime(new Date());

			if (homeworkComplates.size() > 0) {

				MidoHomeworkComplate midoHomeworkComplate = homeworkComplates.get(homeworkComplates.size() - 1);

				complate.setId(midoHomeworkComplate.getId());

				complateMapper.updateById(complate);
			} else {
				//新建完成详情表
				complateMapper.insert(complate);
			}

			BeanUtils.copyProperties(complate, homeworkComplateWeek);
			//已完成
			homeworkComplateWeek.setFlag("1");
			//memberId
			homeworkComplateWeek.setMemberId(SecurityUtils.getMember().getId());
			//曲目时长改用作业主表的曲目时长(因为需要分段/分小节，所以曲目的标准时长由前端进行计算)
			if (midoHomeworkMain.getMusicLength() != null) {
				homeworkComplateWeek.setMusicLength(midoHomeworkMain.getMusicLength());
			}
			complateWeekMapper.insert(homeworkComplateWeek);

			//更新作业状态为【已完成】
			midoHomeworkMain.setStatus(HomeWorkConstants.COMPELTED);
			//构建【高光时刻】的数据【第几遍】【最高分】【最高分的完成情况表ID】
			List<MidoHomeworkComplateWeek> midoHomeworkMainBest = complateWeekMapper.getHomeworkBest(midoHomeworkMain.getId());
			int bestNum = 0;
			int bestScore = 0;

			for (int i = 0; i < midoHomeworkMainBest.size(); i++) {
				if (i == 0) {
					bestNum = 0;
					bestScore = midoHomeworkMainBest.get(i).getTotalScore();
					continue;
				} else {
					if (bestScore < midoHomeworkMainBest.get(i).getTotalScore()) {
						bestScore = midoHomeworkMainBest.get(i).getTotalScore();
						bestNum = i;
					}
				}
			}

			midoHomeworkMain.setBestNum(bestNum + 1);
			midoHomeworkMain.setBestNumComplateId(midoHomeworkMainBest.get(bestNum).getId());
			midoHomeworkMain.setBestScore(bestScore);

			//更新
			homeworkMainMapper.updateById(midoHomeworkMain);
		}

		//推送作业 - 异常记录返回 true
		try {
			//推送消息的场合 : 不是试听作业 并且 是教师模式
			if (!HomeWorkConstants.AUDITION_MODE.equals(midoHomeworkMain.getPlayingMode()) && HomeWorkConstants.TEACHER_MODE
					.equals(midoHomeworkMain.getIsParentMode())) {

				// 查询此作业的批次ID，看是否这一组作业全部完成全部完成
				Long groupId = midoHomeworkMain.getGroupId();
				//作业开始时间
				String startDate = new SimpleDateFormat("yyyy-MM-dd").format(midoHomeworkMain.getStartDate());
				//获取作业信息
				List<MidoHomeworkMain> homeworkMains = homeworkMainMapper
						.getHomeworkPush(groupId, midoHomeworkMain.getPlayingMode(), startDate);
				//全完成才给推送
				boolean isPush = homeworkMains.stream().allMatch(x -> HomeWorkConstants.COMPELTED.equals(x.getStatus()));
				if (isPush) {
					// 获取教师的 memberId
					String memberId = homeworkMainMapper.getTeacherId(midoHomeworkMain.getTeacherId());
					// 推送消息
					String regId = homeworkMainMapper.getRegIdByMemberId(memberId);
					// 获取学生的昵称
					String studentName = homeworkMainMapper.getMemberNameByStuId(midoHomeworkMain.getStudentId());
					//旧版本推送内容为学生ID
					if (StringUtils.isEmpty(complate.getVersion())) {
						JSONArray jsonArray = new JSONArray();
						jsonArray.add(midoHomeworkMain.getStudentId());
						//推送 message
						JPushUtils
								.sendJMessage(JPushCodeEnum.J_PUSH_STUDENT_COMMIT_HOMEWORK.getType(), regId, jsonArray.toJSONString());
					}
					//新版本推送内容新增作业开始时间,用键值对形式返回
					else {
						JsonObject jsonObject = new JsonObject();
						jsonObject.addProperty("studentId", midoHomeworkMain.getStudentId());
						jsonObject.addProperty("startDate", startDate);
						JPushUtils.sendJMessage(JPushCodeEnum.J_PUSH_STUDENT_COMMIT_HOMEWORK.getType(), regId, jsonObject.toString());
					}
					//新增消息体 - 提交作业（完成作业）
					String msgId = addMsg("您的学生 " + studentName + " 已经完成了作业,快来看看吧", regId);
					//调用 feign 保存个人站内消息
					MsgMemberInfo msgMemberInfo = new MsgMemberInfo();
					//阅读状态：未读
					msgMemberInfo.setReadStatus("0");
					//创建时间
					msgMemberInfo.setCreateTime(LocalDateTime.now());
					//创建人 系统创建
					msgMemberInfo.setCreateUser("sys");
					//有效数据
					msgMemberInfo.setDelFlag(CommonConstants.STATUS_NORMAL);
					//发送方ID 0-系统发送
					msgMemberInfo.setFromId("0");
					//接收方ID - memberId
					msgMemberInfo.setToId(memberId);
					//消息信息
					msgMemberInfo.setMsgId(msgId);
					//作业数据
					msgMemberInfo.setHomeworkData(
							createHomeworkData(midoHomeworkMain, startDate, midoHomeworkMain.getStudentId(), studentName));
					//发送
					remotePushService.sendMsg(msgMemberInfo);
					//通知 APP 请求指定接口
					JPushUtils.sendJMessage(JPushCodeEnum.J_PUSH_APP_HOMEPAGE_VIEW.getType(), regId, "请调用 getMsgApp 接口");
					//推送消息
					JPushUtils.sendJPush(SUBMIT_HOMEWORK_PUSH_TITLE, "您的学生 " + studentName + " 已经完成了作业,快来看看吧", regId);
				}
			}

		} catch (Exception e) {
			return homeworkComplateWeek;
		}

		return homeworkComplateWeek;
	}

	@Override
	public boolean submitHomworkWeekNon(MidoHomeworkComplateVO complate) {
		//检索作业表
		MidoHomeworkMain midoHomeworkMain = homeworkMainMapper.selectById(complate.getHomeworkId());
		//保存学生ID
		complate.setStudentId(midoHomeworkMain.getStudentId());
		// 保存complate week 信息用于计算周报
		MidoHomeworkComplateWeek homeworkComplateWeek = new MidoHomeworkComplateWeek();
		BeanUtils.copyProperties(complate, homeworkComplateWeek);
		//未完成完成
		homeworkComplateWeek.setFlag("0");
		//memberId
		homeworkComplateWeek.setMemberId(SecurityUtils.getMember().getId());
		//曲目时长改用作业主表的曲目时长(因为需要分段/分小节，所以曲目的标准时长由前端进行计算)
		if (midoHomeworkMain.getMusicLength() != null) {
			homeworkComplateWeek.setMusicLength(midoHomeworkMain.getMusicLength());
		}
		return complateWeekMapper.insert(homeworkComplateWeek) == 1;
	}

	private String createHomeworkData(MidoHomeworkMain midoHomeworkMain, String startDate, String studentId, String studentName) {

		//构建推送响应体
		JsonObject jsonObject = new JsonObject();
		//获取学生信息
		StudentVO studentInfo = remoteMemberService.getStudentInfoFeign(studentId);
		//学生ID
		jsonObject.addProperty("studentId", studentId);
		//作业时间
		jsonObject.addProperty("startDate", startDate);
		//学生姓名
		jsonObject.addProperty("studentMemberShowName", studentName);
		//学生头像
		jsonObject.addProperty("header", studentInfo.getHead());

		jsonObject.addProperty("imId", studentInfo.getImId());

		//classRoomId 查询此教师和学生是否是个人师生关系
		String teacherId = midoHomeworkMain.getTeacherId();

		String classroomId = remoteMemberService.getClassroomId(teacherId, studentId);
		//班级ID
		jsonObject.addProperty("classroomId", classroomId);
		return jsonObject.toString();
	}

	private String addMsg(String message, String regId) {

		MsgMain msgMain = new MsgMain();
		//给教师发送
		msgMain.setTriggerTo("1");
		//来自学生完成的作业 - 系统自动推送
		msgMain.setTriggerFrom("0");
		//消息下发的场合：完成作业
		msgMain.setPoint("2");
		//不可修改
		msgMain.setModify("0");
		//自动推送
		msgMain.setMode("1");
		//个人
		msgMain.setRangeType("1");
		//有效数据
		msgMain.setDelFlag("0");
		//创建时间
		msgMain.setCreateTime(LocalDateTime.now());
		//消息类型：文本
		msgMain.setMsgType("0");
		//发送时间
		msgMain.setActualPubDatetime(LocalDateTime.now());
		//创建人-> 系统
		msgMain.setCreateUser("sys");
		//消息内容
		msgMain.setMessage(message);
		//发布时间
		msgMain.setPubDatetime(LocalDateTime.now());
		//极光推送唯一ID
		msgMain.setPushId(regId);
		//推送成功
		msgMain.setPushStatus("0");
		//推送时间
		msgMain.setPushTime(LocalDateTime.now());
		//标题
		msgMain.setTitle(SUBMIT_HOMEWORK_PUSH_TITLE);
		//系统消息
		msgMain.setType("0");

		return (String) remotePushService.addMsg(msgMain).getData();
	}


}
